/*
* Copyright (C) 2020 ~ 2024 chaigec All Rights Reserved.
*
* Author:     chaigec <chaigec@163.com>
* Maintainer: chaigec <chaigec@163.com>

 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
*/

#include "MkGb28181/MkGb28181.h"
#include "MkEvent/MkTimer.h"
#include "MkEvent/MkEventPool.h"
#include <MkUtil/MkUtil.h>
#include <MkUtil/MkLog.h>
#include <signal.h>

CMkGb28181 *pGb = nullptr;
CMkTimer  g_Timer;
MkString  g_DeviceId;
MkString  g_ChannelId = "34020000001310000002";
MkString  g_PlaySession;
BOOL g_bOnline = FALSE;

int main(int argc, char ** argv)
{
#ifdef _WIN32
    WSADATA WSAData;
    WSAStartup(0x101, &WSAData);
#else
    signal(SIGPIPE, SIG_IGN);  //ignore sigpipe
#endif
    MkLogChangeLevel(LOG_DEBUG);
    CMkEventPool Pool;

    Pool.Start(1);
    g_Timer.StartTimerThread();
    pGb = new CMkGb28181(&Pool,&g_Timer);

    signal(SIGINT, [](int sig) {
        if (SIGINT == sig) {
            g_Timer.LoopBreak();
        }
    });// set exit  signal
    MkGbStartParam Param;
    Param.LocalHost = "192.168.0.13";
    Param.LocalPort = 5060;
    Param.SipId = "34020000002000000001";
    Param.SipRealm = "3402020000";
    Param.RegisterExpires = 3600;
    Param.SubscribeExpires = 3600;
    //pGb->Start(Param, [](const CMkGbRequestBase *pRequest, const MkGbResponseCallback& Cb) {
    //    if (!g_bOnline && MkGbDeviceAuthor != pRequest->GetType()) {
    //        return InvalidParams;
    //    }
    //    switch (pRequest->GetType()) {
    //    case MkGbDeviceAuthor:
    //        MkDebugLog("recv device:%s dst:%s author\n", pRequest->GetDeviceId().c_str(), pRequest->GetDstId().c_str());
    //        if (Cb)
    //        {
    //            CMkGbDeviceAuthorResponse Res(pRequest->GetDeviceId(), pRequest->GetDstId(),FALSE,"",0);
    //            Cb(NoneError, &Res);
    //            g_DeviceId = pRequest->GetDeviceId();
    //            g_bOnline = TRUE;
    //        }
    //        break;
    //    case MkGbDeviceKeepAlive:
    //        MkDebugLog("recv device:%s dst:%s keepalive\n", pRequest->GetDeviceId().c_str(), pRequest->GetDstId().c_str());
    //        break;
    //    default:
    //        break;
    //    }
    //    return NoneError;
    //});

    //char GetC;
    //while (GetC = getchar())
    //{
    //    BOOL bQuit = FALSE;
    //    MkDebugLog("get char:%c\n", GetC);
    //    switch (GetC) {
    //    case '1': //get catalog
    //        pGb->GetCatalog(g_DeviceId, g_DeviceId, [](Uint32 ErrorCode, const CMkGbResponseBase* pRes) {
    //            const CMkGbCatalogResponse* pCatalRes = dynamic_cast<const CMkGbCatalogResponse*>(pRes);
    //            //MkGbVectorCatlog::const_iterator it = pCatalRes->GetCatalog().begin();
    //            //for (; it != pCatalRes->GetCatalog().end(); it++) {
    //            //    MkDebugLog("channelid:%s  online:%d\n", it->Id.c_str(),it->Online);
    //            //    //if (("132" == it->Id.substr(10, 3) || "131" == it->Id.substr(10, 3))
    //            //    //    && it->Online && g_ChannelId.empty()) {
    //            //    //    g_ChannelId = it->Id;
    //            //    //}
    //            //}
    //        });
    //        break;
    //    case '2': //real play
    //    {
    //        //MkGbPlayParam Param;
    //        //Param.bTcp = FALSE;
    //        //Param.RtpHost = "192.168.0.13";
    //        //Param.RtpPort = 55555;
    //        //Param.RtpSsrc = 0x123;
    //        //Param.PlayType = MkGbRealPlay;
    //        //CMkUtil::CreateRandomString(Len16, Param.Session);
    //        //g_PlaySession = Param.Session;
    //        //pGb->Play(g_DeviceId, g_ChannelId, Param, [](Uint32 ErrorCode, const CMkGbResponseBase* pRes) {
    //        //    MkDebugLog("gb realplay error code:%d\n", ErrorCode);
    //        //});
    //    }
    //        break;
    //    case '3': //stop realplay
    //        pGb->Bye(g_PlaySession,nullptr);
    //        break;
    //    case '4': //ptz up
    //        pGb->PtzControl(g_DeviceId, g_ChannelId, MkGbPtzUp, 0, 255, 0,nullptr);
    //        break;
    //    case '5': //ptz stop
    //        pGb->PtzControl(g_DeviceId, g_ChannelId, MkGbPtzStop, 0, 0, 0,nullptr);
    //        break;
    //    case '6': //set preset
    //        pGb->PtzControl(g_DeviceId, g_ChannelId, MkGbPtzSetPreset, 0, 1, 0,nullptr);
    //        break;
    //    case '7':
    //        pGb->GetPreset(g_DeviceId, g_ChannelId, [](Uint32 ErrorCode, const CMkGbResponseBase* pRes) {
    //            const CMkGbPresetResponse* pResponse = dynamic_cast<const CMkGbPresetResponse*>(pRes);
    //            MkGbVectorPreset::const_iterator it = pResponse->GetPreset().begin();
    //            for (;it != pResponse->GetPreset().end();it++)
    //            {
    //                MkDebugLog("get preset id:%d name:%s\n",it->PresetId, it->PresetName.c_str());
    //            }
    //        });
    //        break;
    //    case '8':  //delete preset
    //        pGb->PtzControl(g_DeviceId, g_ChannelId, MkGbPtzClearPreset, 0, 1, 0,nullptr);
    //        break;
    //    case '9': //home positon
    //    {
    //        MkGbHomePositionParam Param;
    //        Param.bEnabled = TRUE;
    //        Param.PresetIndex = 1;
    //        Param.ResetSecond = 10;
    //        pGb->HomePosition(g_DeviceId, g_ChannelId, Param, [](Uint32 ErrorCode, const CMkGbResponseBase* pRes) {
    //            MkDebugLog("set home position result:%d\n", ErrorCode);
    //        });
    //    }
    //        break;
    //    case '0': //key frame
    //        pGb->ChannelKeyFrame(g_DeviceId, g_ChannelId, [](Uint32 ErrorCode, const CMkGbResponseBase* pRes) {
    //            MkDebugLog("set key frame result:%d\n", ErrorCode);
    //        });
    //        break;
    //    case 'a': // find record
    //    {
    //        MkGbFindRecordParam Param;
    //        Param.StartTime = NowMkTime - (Uint64)60 * 60 * 1000 * 1000;
    //        Param.EndTime = NowMkTime;
    //        Param.RecordType = MkGbAllRecord;
    //        pGb->FindRecord(g_DeviceId, g_ChannelId, Param, [](Uint32 ErrorCode, const CMkGbResponseBase* pRes) {
    //            MkDebugLog("set find record result:%d\n", ErrorCode);
    //            const CMkGbFindRecordResponse* pResponse = dynamic_cast<const CMkGbFindRecordResponse*>(pRes);
    //            if (pResponse)
    //            {
    //                MkGbVectorRecordInfo::const_iterator it = pResponse->GetVecRecordInfo().begin();
    //                for (;it != pResponse->GetVecRecordInfo().end();it++)
    //                {
    //                    MkString StartTime;
    //                    MkString EndTime;
    //                    it->StartTime.GetString(StartTime);
    //                    it->EndTime.GetString(EndTime);
    //                    MkDebugLog("find record response:%s %s %d\n", StartTime.c_str(), EndTime.c_str(), it->RecordType);
    //                }
    //            }
    //        });
    //    }
    //        break;
    //    case 'b': //Manual record
    //        pGb->ManualRecord(g_DeviceId, g_ChannelId, [](Uint32 ErrorCode, const CMkGbResponseBase* pRes) {
    //            MkDebugLog("manual rerecord result:%d\n", ErrorCode);
    //        });
    //        break;
    //    case 'c':
    //        pGb->StopManualRecord(g_DeviceId, g_ChannelId, [](Uint32 ErrorCode, const CMkGbResponseBase* pRes) {
    //            MkDebugLog("stop manual rerecord result:%d\n", ErrorCode);
    //        });
    //        break;
    //    case 'd': //device status
    //        pGb->GetDeviceStatus(g_DeviceId, g_DeviceId, [](Uint32 ErrorCode, const CMkGbResponseBase* pRes) {
    //            MkDebugLog("get device status result:%d\n", ErrorCode);
    //        });
    //        break;
    //    case 'e':
    //        pGb->GetDeviceInfo(g_DeviceId, g_DeviceId, [](Uint32 ErrorCode, const CMkGbResponseBase* pRes) {
    //            MkDebugLog("get device info result:%d\n", ErrorCode);
    //        });
    //        break;
    //    case 'f':
    //    {
    //        //MkGbPlayParam Param;
    //        //Param.bTcp = FALSE;
    //        //Param.RtpHost = "192.168.0.13";
    //        //Param.RtpPort = 55555;
    //        //Param.RtpSsrc = 0x123;
    //        //Param.BeginTime = NowMkTime - (Uint64)60 * 60 * 1000 * 1000;
    //        //Param.EndTime = NowMkTime;
    //        //Param.PlayType = MkGbDownload;
    //        //Param.Speed = 8;
    //        //CMkUtil::CreateRandomString(Len16, Param.Session);
    //        //g_PlaySession = Param.Session;
    //        //pGb->Play(g_DeviceId, g_ChannelId, Param, [](Uint32 ErrorCode, const CMkGbResponseBase* pRes) {
    //        //    MkDebugLog("gb realplay error code:%d\n", ErrorCode);
    //        //});
    //    }
    //    break;
    //    case  'g':
    //    {
    //        //MkGbPlayParam Param;
    //        //Param.bTcp = FALSE;
    //        //Param.RtpHost = "192.168.0.13";
    //        //Param.RtpPort = 55555;
    //        //Param.RtpSsrc = 0x123;
    //        //Param.BeginTime = NowMkTime - (Uint64)60 * 60 * 1000 * 1000;
    //        //Param.EndTime = NowMkTime;
    //        //Param.PlayType = MkGbPlayback;
    //        //CMkUtil::CreateRandomString(Len16, Param.Session);
    //        //g_PlaySession = Param.Session;
    //        //pGb->Play(g_DeviceId, g_ChannelId, Param, [](Uint32 ErrorCode, const CMkGbResponseBase* pRes) {
    //        //    MkDebugLog("gb realplay error code:%d\n", ErrorCode);
    //        //});
    //    }
    //    break;
    //    case 'h':
    //        pGb->PlayControl(g_PlaySession, MkGbPause, 0.0f, CMkTime(), [](Uint32 ErrorCode, const CMkGbResponseBase* pRes) {
    //            MkDebugLog("play control result:%d\n", ErrorCode);
    //        });
    //        break;
    //    case 'i':
    //        pGb->PlayControl(g_PlaySession, MkGbReStore, 0.0f, CMkTime(), [](Uint32 ErrorCode, const CMkGbResponseBase* pRes) {
    //            MkDebugLog("play control result:%d\n", ErrorCode);
    //        });
    //        break;
    //    case 'j':
    //        pGb->RebootDevice(g_DeviceId, g_DeviceId, [](Uint32 ErrorCode, const CMkGbResponseBase* pRes) {
    //            MkDebugLog("play control result:%d\n", ErrorCode);
    //        });
    //        break;
    //    case 'k':
    //        //pGb->GetBasicConfig(g_DeviceId, g_DeviceId, [](Uint32 ErrorCode, const CMkGbResponseBase* pRes) {
    //        //    MkDebugLog("play control result:%d\n", ErrorCode);
    //        //});
    //        break;
    //    case 'l':
    //        pGb->MobilePositionSubscribe(g_DeviceId, g_ChannelId, NowMkTime, NowMkTime + (Uint64)60 * 60 * 1000 * 1000, 10, [](Uint32 ErrorCode, const CMkGbResponseBase* pRes) {
    //            MkDebugLog("play control result:%d\n", ErrorCode);
    //        });
    //        break;
    //    case 'm':
    //        pGb->StartBroadcast(g_DeviceId, "340200000011700000001", "340200000011600000001", [](Uint32 ErrorCode, const CMkGbResponseBase* pRes) {
    //            MkDebugLog("play control result:%d\n", ErrorCode);
    //        });
    //        break;
    //    case 'n':
    //        break;
    //    case 'q':
    //        bQuit = TRUE;
    //        break;
    //    default:
    //        break;
    //    }
    //    if (bQuit) {
    //        break;
    //    }
    //}

    g_Timer.StopTimerThread();
    Pool.Stop();
    pGb->Stop();
    MkDelete(pGb);
#ifdef _WIN32
    WSACleanup();
#endif
    printf("end\n");
    return 1;
}